#pragma once

#include "call_agent_interface.hpp"
#include "sfu_client.hpp"

namespace p2pms
{

//==================================================================================================
// SFUCallAgent is a wrapper around P2SPCallAgent with room-specific semantics
//==================================================================================================
class SFUCallAgent : public ICallAgent, public ISFUClientHandler
{
public:
	SFUCallAgent(
		const std::string& user_id,
		IPcFactoryPtr factory,
		ICallHandler* handler, 
		rtc::Thread* thread,
		std::shared_ptr<IMsgDispatcher> dispatcher);
	~SFUCallAgent() override = default;

	// ICallAgent
	ErrCode Init() override;
	ErrCode MakeCall(const std::string& callee_id) override;
	ErrCode IncomingCall(const CallMakeNotifyData& notify_data) override;
	void TerminateCall() override;
	ErrCode StartPublish(const MediaInfo& media) override;
	ErrCode StopPublish(const MediaInfo& media) override;
	ErrCode StartSubscribe(const std::string& user_id, const MediaInfo& media) override;
	ErrCode StopSubscribe(const std::string& user_id, const MediaInfo& media) override;
	CallMode GetCallMode() override;
	std::string GetCallerId() override;
	std::string GetCalleeId() override;
	std::string GetCallId() override;
	std::string GetPeerUserId() override;
	std::string GetUserId() override;
	CallState GetCallState() override;
	void OnTimer() override;

	// ISFUClientHandler
	void OnJoinRoomResult(bool result) override;
	void OnStartPublishResult(
		const MediaInfo& media,
		bool result) override;
	void OnStopPublishResult(
		const MediaInfo&
		media, bool result) override;
	void OnStartPublishNotify(
		const std::string& user_id,
		const MediaInfo& media) override;
	void OnStopPublishNotify(
		const std::string& user_id,
		const MediaInfo& media) override;
	void OnStartSubscribeResult(
		const std::string& user_id,
		const MediaInfo& media,
		bool result) override;
	void OnStopSubscribeResult(
		const std::string& user_id,
		const MediaInfo& media,
		bool result) override;
	void OnAddTrack(
		const std::string& user_id,
		const MediaInfo& media,
		webrtc::MediaStreamTrackInterface* track) override;
	void OnRemoveTrack(
		const std::string& user_id,
		const MediaInfo& media,
		webrtc::MediaStreamTrackInterface* track) override;

private:
	void CallStateChanged(CallState state);

private:
	std::string m_room_id;
	std::string m_user_id;
	CallState m_call_state = CallState::Idle;
	ICallHandler* m_call_handler = nullptr;
	SFUClient m_sfu_client;
};

}